﻿//+--------------------------------------------------------------------------------------------------
//     
//Description:  ApplicationProfileViewModel
//Author: Aravind Ramarathinam (aravr@microsoft.com)
//Copyright © Microsoft Corporation
//Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. 
//You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 
//
//THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, 
//INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT. 
//See the Apache Version 2.0 License for specific language governing permissions and limitations under the License.
// 
//--------------------------------------------------------------------------------------------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Input;
using VmroleAuthor.Commands;
using VmroleAuthor.Models;

namespace VmroleAuthor.ViewModels
{
    public class ApplicationProfileViewModel : TreeViewItemViewModel, IAddWebDeployApplication, IAddProvisioningScript, IAddScriptApplication, IAddSqldacApplication, IAddSqlProfile, IDataErrorInfo, IProduceValidationResults, IRemoveChildItem
    {
        private readonly ExtensionSettings extensionSettings;         
        private readonly ObservableCollection<ApplicationPayloadViewModel> applicationPayloadViewModels;      
        private readonly VmRoleResourceExtensionViewModel vmRoleResourceExtensionViewModel;        

        public static class PropertyNames
        {
            public const string Summary = "Summary";
            public const string Name = "Name";       
            public const string ApplicationPayloads = "ApplicationPayloads";
        }
       
        public ApplicationProfileViewModel(ExtensionSettings extensionSettings, VmRoleResourceExtensionViewModel resourceExtensionViewModel)
            : base(resourceExtensionViewModel, true)
        {
            this.extensionSettings = extensionSettings;
            this.vmRoleResourceExtensionViewModel = resourceExtensionViewModel;            
            if (this.extensionSettings.ApplicationProfile == null)
            {
                this.extensionSettings.ApplicationProfile = new ApplicationProfile();
            }
            this.applicationPayloadViewModels = new ObservableCollection<ApplicationPayloadViewModel>();           
            if (this.extensionSettings.ApplicationProfile.ApplicationPayload != null)
            {
                foreach (ApplicationPayload applicationPayload in this.extensionSettings.ApplicationProfile.ApplicationPayload)
                {
                    var appPayloadViewModel = new ApplicationPayloadViewModel(applicationPayload, this.vmRoleResourceExtensionViewModel);
                    this.applicationPayloadViewModels.Add(appPayloadViewModel);                 
                }
            }

            this.AddApplicationPayloadCommand = new RelayCommand(
             param => this.AddApplicationPayload(),
             param => this.CanAddApplicationPayload());

            this.RemoveApplicationPayloadCommand = new RelayCommand(
                param => this.RemoveApplicationPayload((ApplicationPayloadViewModel)param),
                param => this.CanRemoveApplicationPayload((ApplicationPayloadViewModel)param));  
            
            this.ValidationResults = new ObservableCollection<CloudServiceModelValidationResult>();
        }

        public string Summary
        {
            get
            {                
                if (this.extensionSettings.ApplicationProfile.WindowsApplicationProfile != null && this.extensionSettings.ApplicationProfile.LinuxApplicationProfile != null)
                {
                    return "Application Profile (Error - Both Windows And Linux defined)";
                }
                if (this.extensionSettings.ApplicationProfile.WindowsApplicationProfile == null && this.extensionSettings.ApplicationProfile.LinuxApplicationProfile == null)
                {
                    return "Application Profile (Error - Neither Windows Or Linux defined)";
                }
                if (this.extensionSettings.ApplicationProfile.WindowsApplicationProfile != null)
                {
                    return "Application Profile (Windows)";
                }
                return "Application Profile (Linux)";
            }
        }       

        public string Name
        {
            get
            {
                return this.extensionSettings.ApplicationProfile.Name;
            }
            set
            {
                this.extensionSettings.ApplicationProfile.Name = value; 
                this.OnPropertyChanged(PropertyNames.Name);
            }
        }

        public ObservableCollection<ApplicationPayloadViewModel> ApplicationPayloads
        {
            get
            {
                return this.applicationPayloadViewModels;
            }
        }

        public ICommand AddApplicationPayloadCommand { get; private set; }

        public ICommand RemoveApplicationPayloadCommand { get; private set; }

        public bool CanAddApplicationPayload()
        {
            return true;
        }

        public void AddApplicationPayload()
        {
            ApplicationPayload payload = new ApplicationPayload();
            this.AddApplicationPayload(payload);         
        }

        public void AddApplicationPayload(ApplicationPayload payload)
        {
            this.extensionSettings.ApplicationProfile.ApplicationPayload.Add(payload);
            ApplicationPayloadViewModel payloadViewModel = new ApplicationPayloadViewModel(payload, this.vmRoleResourceExtensionViewModel);
            this.applicationPayloadViewModels.Add(payloadViewModel);        
        }

        public bool CanRemoveApplicationPayload(ApplicationPayloadViewModel payloadViewModel)
        {
            return true;
        }

        public void RemoveApplicationPayload(ApplicationPayloadViewModel payloadViewModel)
        {
            if (payloadViewModel != null)
            {
                this.extensionSettings.ApplicationProfile.ApplicationPayload.Remove(payloadViewModel.ApplicationPayload);
                this.extensionSettings.ApplicationProfile.ApplicationPayload.RemoveAll(payload => string.Compare(payloadViewModel.RelativePath, payload.RelativePath,StringComparison.OrdinalIgnoreCase) == 0);
                this.applicationPayloadViewModels.Remove(payloadViewModel);               
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="appPayloadId"></param>
        /// <returns> null if not found </returns>
        public ApplicationPayloadViewModel GetApplicationPayloadViewModel(string appPayloadId)
        {        
            if (appPayloadId == null)
            {
                return null;
            }
            return this.applicationPayloadViewModels.FirstOrDefault(applicationPayloadViewModel => appPayloadId.Equals(applicationPayloadViewModel.Id, StringComparison.OrdinalIgnoreCase));
        }
     

        public ApplicationPayloadViewModel GetApplicationPayloadViewModelFromRelativePath(string relativePath)
        {            
            if (relativePath == null)
            {
                return null;
            }
            ApplicationPayloadViewModel result = this.applicationPayloadViewModels.FirstOrDefault(applicationPayloadViewModel => relativePath.Equals(applicationPayloadViewModel.RelativePath, StringComparison.OrdinalIgnoreCase));
            // Exact match not found. Try using ./ or .\\ prefixes
            if (result == null)
            {
                result = this.applicationPayloadViewModels.FirstOrDefault(
                    applicationPayloadViewModel => 
                        relativePath.Equals("./" + applicationPayloadViewModel.RelativePath, StringComparison.OrdinalIgnoreCase) ||
                        relativePath.Equals(".\\" + applicationPayloadViewModel.RelativePath, StringComparison.OrdinalIgnoreCase));               
            }
            return result;
        }

        
        public int GetApplicationPayloadReferenceCount(string applicationPayloadId)
        {
            int count = 0;
            if (this.vmRoleResourceExtensionViewModel.ResourceExtensionDefinition.ExtensionSettings == null ||
                this.vmRoleResourceExtensionViewModel.ResourceExtensionDefinition.ExtensionSettings.ApplicationProfile == null ||
                this.vmRoleResourceExtensionViewModel.ResourceExtensionDefinition.ExtensionSettings.ApplicationProfile.WindowsApplicationProfile == null)
            {
                return count;
            }

            //Check all web deploy apps
            if (this.vmRoleResourceExtensionViewModel.ResourceExtensionDefinition.ExtensionSettings.ApplicationProfile.WindowsApplicationProfile.WebDeployApplications != null)
            {
                foreach (var webDeployApplication in this.vmRoleResourceExtensionViewModel.ResourceExtensionDefinition.ExtensionSettings.ApplicationProfile.WindowsApplicationProfile.WebDeployApplications)
                {
                    if (webDeployApplication != null && string.Compare(webDeployApplication.ApplicationPayloadId, applicationPayloadId, StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        ++count;
                    }
                    if (webDeployApplication != null && webDeployApplication.ScriptCommands != null)
                    {
                        count += webDeployApplication.ScriptCommands.Count(scriptCommand => scriptCommand != null && string.Compare(scriptCommand.ApplicationPayloadId, applicationPayloadId, StringComparison.OrdinalIgnoreCase) == 0);
                    }
                }
            }

            //Check all script apps
            if (this.vmRoleResourceExtensionViewModel.ResourceExtensionDefinition.ExtensionSettings.ApplicationProfile.WindowsApplicationProfile.ScriptApplications != null)
            {
                foreach (var scriptApplication in this.vmRoleResourceExtensionViewModel.ResourceExtensionDefinition.ExtensionSettings.ApplicationProfile.WindowsApplicationProfile.ScriptApplications)
                {
                    if (scriptApplication != null && string.Compare(scriptApplication.ApplicationPayloadId, applicationPayloadId, StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        ++count;
                    }
                    if (scriptApplication  != null && scriptApplication.ScriptCommands != null)
                    {
                        count += scriptApplication.ScriptCommands.Count(scriptCommand => scriptCommand != null && string.Compare(scriptCommand.ApplicationPayloadId, applicationPayloadId, StringComparison.OrdinalIgnoreCase) == 0);
                    }
                }
            }

            //Check all provisioning scripts
            if (this.vmRoleResourceExtensionViewModel.ResourceExtensionDefinition.ExtensionSettings.ApplicationProfile.WindowsApplicationProfile.ProvisioningScripts != null)
            {
                count += this.vmRoleResourceExtensionViewModel.ResourceExtensionDefinition.ExtensionSettings.ApplicationProfile.WindowsApplicationProfile.ProvisioningScripts.Count(provisioningScript => provisioningScript != null && string.Compare(provisioningScript.ApplicationPayloadId, applicationPayloadId, StringComparison.OrdinalIgnoreCase) == 0);
            }

            //Check all SQL DAC apps
            if (this.vmRoleResourceExtensionViewModel.ResourceExtensionDefinition.ExtensionSettings.ApplicationProfile.WindowsApplicationProfile.SQLDacApplications != null)
            {
                foreach (var sqlDacApplication in this.vmRoleResourceExtensionViewModel.ResourceExtensionDefinition.ExtensionSettings.ApplicationProfile.WindowsApplicationProfile.SQLDacApplications)
                {
                    if (sqlDacApplication != null && string.Compare(sqlDacApplication.ApplicationPayloadId, applicationPayloadId, StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        ++count;
                    }
                    if (sqlDacApplication != null && sqlDacApplication.ScriptCommands != null)
                    {
                        count += sqlDacApplication.ScriptCommands.Count(scriptCommand => scriptCommand != null && string.Compare(scriptCommand.ApplicationPayloadId, applicationPayloadId, StringComparison.OrdinalIgnoreCase) == 0);
                    }
                    if (sqlDacApplication != null && sqlDacApplication.SQLScriptCommands != null)
                    {
                        count += sqlDacApplication.SQLScriptCommands.Count(sqlScriptCommand => sqlScriptCommand != null && string.Compare(sqlScriptCommand.SQLScriptApplicationPayloadId, applicationPayloadId, StringComparison.OrdinalIgnoreCase) == 0);
                    }
                }
            }

            //Check SQL Profile
            if (this.vmRoleResourceExtensionViewModel.ResourceExtensionDefinition.ExtensionSettings.ApplicationProfile.WindowsApplicationProfile.SQLProfile != null &&
                this.vmRoleResourceExtensionViewModel.ResourceExtensionDefinition.ExtensionSettings.ApplicationProfile.WindowsApplicationProfile.SQLProfile.SQLDeployments != null)
            {
                count += this.vmRoleResourceExtensionViewModel.ResourceExtensionDefinition.ExtensionSettings.ApplicationProfile.WindowsApplicationProfile.SQLProfile.SQLDeployments.Where(sqlDeployment => sqlDeployment != null).Count(sqlDeployment => string.Compare(sqlDeployment.SQLConfigurationFilePayloadId, applicationPayloadId, StringComparison.OrdinalIgnoreCase) == 0);
            }         
            return count;
        }
       


        public bool CanAddWebDeployApplication
        {
            get { return this.extensionSettings.ApplicationProfile.WindowsApplicationProfile != null;  }
        }

        public void AddWebDeployApplication()
        {
            this.IsExpanded = true; //critical to be done first
            Debug.Assert(this.extensionSettings.ApplicationProfile.WindowsApplicationProfile != null) ;
            WebDeployApplication webDeployApplication = new WebDeployApplication();
            webDeployApplication.DeploymentName = this.vmRoleResourceExtensionViewModel.Name;
            if (this.extensionSettings.ApplicationProfile.WindowsApplicationProfile.WebDeployApplications == null)
            {
                this.extensionSettings.ApplicationProfile.WindowsApplicationProfile.WebDeployApplications = new List<WebDeployApplication>();
            }            
            this.extensionSettings.ApplicationProfile.WindowsApplicationProfile.WebDeployApplications.Add(webDeployApplication);
            var webDeployViewModel = new WebDeployApplicationViewModel(webDeployApplication, this, this.vmRoleResourceExtensionViewModel);            
            this.Children.Add(webDeployViewModel);
            webDeployViewModel.IsSelected = true;            
        }

        public bool CanAddProvisioningScript
        {
            get { return this.extensionSettings.ApplicationProfile.WindowsApplicationProfile != null;  }         
        }

        public void AddProvisioningScript()
        {
            this.IsExpanded = true; //critical to be done first
            Debug.Assert(this.extensionSettings.ApplicationProfile.WindowsApplicationProfile != null);
            ProvisioningScript provisioningScript = new ProvisioningScript();            
            if (this.extensionSettings.ApplicationProfile.WindowsApplicationProfile.ProvisioningScripts == null)
            {
                this.extensionSettings.ApplicationProfile.WindowsApplicationProfile.ProvisioningScripts = new List<ProvisioningScript>();
            }
            this.extensionSettings.ApplicationProfile.WindowsApplicationProfile.ProvisioningScripts.Add(provisioningScript);
            var provisioningScriptViewModel = new ProvisioningScriptViewModel(provisioningScript, this, this.vmRoleResourceExtensionViewModel);
            this.Children.Add(provisioningScriptViewModel);
            provisioningScriptViewModel.IsSelected = true;               
        }

        public bool CanAddScriptApplication
        {
            get { return this.extensionSettings.ApplicationProfile.WindowsApplicationProfile != null; }
        }
        public void AddScriptApplication()
        {
            this.IsExpanded = true; //critical to be done first
            Debug.Assert(this.extensionSettings.ApplicationProfile.WindowsApplicationProfile != null);
            ScriptApplication scriptApplication = new ScriptApplication();
            scriptApplication.DeploymentName = this.vmRoleResourceExtensionViewModel.Name;
            if (this.extensionSettings.ApplicationProfile.WindowsApplicationProfile.ScriptApplications == null)
            {
                this.extensionSettings.ApplicationProfile.WindowsApplicationProfile.ScriptApplications = new List<ScriptApplication>();
            }
            this.extensionSettings.ApplicationProfile.WindowsApplicationProfile.ScriptApplications.Add(scriptApplication);
            var scriptAppViewModel = new ScriptApplicationViewModel(scriptApplication, this, this.vmRoleResourceExtensionViewModel);
            this.Children.Add(scriptAppViewModel);
            scriptAppViewModel.IsSelected = true;               
        }

        public bool CanAddSqldacApplication
        {
            get { return this.extensionSettings.ApplicationProfile.WindowsApplicationProfile != null; }
        }

        public void AddSqldacApplication()
        {
            this.IsExpanded = true; //critical to be done first
            Debug.Assert(this.extensionSettings.ApplicationProfile.WindowsApplicationProfile != null);
            SQLDacApplication sqlDacApplication = new SQLDacApplication();
            sqlDacApplication.DeploymentName = this.vmRoleResourceExtensionViewModel.Name;
            if (this.extensionSettings.ApplicationProfile.WindowsApplicationProfile.SQLDacApplications == null)
            {
                this.extensionSettings.ApplicationProfile.WindowsApplicationProfile.SQLDacApplications = new List<SQLDacApplication>();
            }
            this.extensionSettings.ApplicationProfile.WindowsApplicationProfile.SQLDacApplications.Add(sqlDacApplication);
            var sqlDacViewModel = new SqlDacApplicationViewModel(sqlDacApplication, this, this.vmRoleResourceExtensionViewModel);
            this.Children.Add(sqlDacViewModel);
            sqlDacViewModel.IsSelected = true;               
        }


        public bool CanAddSqlProfile
        {
            get
            {
                return this.extensionSettings.ApplicationProfile.WindowsApplicationProfile != null && this.extensionSettings.ApplicationProfile.WindowsApplicationProfile.SQLProfile == null;
            }
        }
        
        public void AddSqlProfile()
        {
            this.IsExpanded = true; //critical to be done first
            Debug.Assert(this.extensionSettings.ApplicationProfile.WindowsApplicationProfile != null);
            Debug.Assert(this.extensionSettings.ApplicationProfile.WindowsApplicationProfile.SQLProfile == null);
            SQLProfile sqlProfile = new SQLProfile();            
            this.extensionSettings.ApplicationProfile.WindowsApplicationProfile.SQLProfile = sqlProfile;
            var sqlProfileViewModel = new SqlProfileViewModel(sqlProfile, this, this.vmRoleResourceExtensionViewModel);
            this.Children.Add(sqlProfileViewModel);
            sqlProfileViewModel.IsSelected = true;  
        }
     


        private void LoadChildrenForWindowsAppProfile()
        {
            Debug.Assert(this.extensionSettings.ApplicationProfile.WindowsApplicationProfile != null);
            if (this.extensionSettings.ApplicationProfile.WindowsApplicationProfile.WindowsServerRolesAndFeatures == null)
            {
                this.extensionSettings.ApplicationProfile.WindowsApplicationProfile.WindowsServerRolesAndFeatures = new List<String>();
            }
            this.Children.Add(new WindowsServerRolesAndFeaturesViewModel(this.extensionSettings.ApplicationProfile.WindowsApplicationProfile.WindowsServerRolesAndFeatures, this));


            if (this.extensionSettings.ApplicationProfile.WindowsApplicationProfile.WebDeployApplications != null)
            {
                foreach (WebDeployApplication webDeployApp in this.extensionSettings.ApplicationProfile.WindowsApplicationProfile.WebDeployApplications)
                {
                    this.Children.Add(new WebDeployApplicationViewModel(webDeployApp, this, this.vmRoleResourceExtensionViewModel));
                }
            }
            if (this.extensionSettings.ApplicationProfile.WindowsApplicationProfile.ScriptApplications != null)
            {
                foreach (ScriptApplication scriptApplication in this.extensionSettings.ApplicationProfile.WindowsApplicationProfile.ScriptApplications)
                {
                    this.Children.Add(new ScriptApplicationViewModel(scriptApplication, this, this.vmRoleResourceExtensionViewModel));
                }
            }
            if (this.extensionSettings.ApplicationProfile.WindowsApplicationProfile.ProvisioningScripts != null)
            {
                foreach (ProvisioningScript provisioningScript in this.extensionSettings.ApplicationProfile.WindowsApplicationProfile.ProvisioningScripts)
                {
                    this.Children.Add(new ProvisioningScriptViewModel(provisioningScript, this, this.vmRoleResourceExtensionViewModel));
                }
            }
            if (this.extensionSettings.ApplicationProfile.WindowsApplicationProfile.SQLDacApplications != null)
            {
                foreach (SQLDacApplication sqldac in this.extensionSettings.ApplicationProfile.WindowsApplicationProfile.SQLDacApplications)
                {
                    this.Children.Add(new SqlDacApplicationViewModel(sqldac, this, this.vmRoleResourceExtensionViewModel));
                }
            }
            if (this.extensionSettings.ApplicationProfile.WindowsApplicationProfile.SQLProfile != null)
            {
                this.Children.Add(new SqlProfileViewModel(this.extensionSettings.ApplicationProfile.WindowsApplicationProfile.SQLProfile, this, this.vmRoleResourceExtensionViewModel));               
            }
        }

        private void LoadChildrenForLinuxAppProfile()
        {
            Debug.Assert(this.extensionSettings.ApplicationProfile.LinuxApplicationProfile != null);
            if (this.extensionSettings.ApplicationProfile.LinuxApplicationProfile.RunOnceCommandHolders == null)
            {
                this.extensionSettings.ApplicationProfile.LinuxApplicationProfile.RunOnceCommandHolders = new List<StringHolder>();
            }
            this.Children.Add(new RunOnceCommandsViewModel(this.extensionSettings.ApplicationProfile.LinuxApplicationProfile.RunOnceCommandHolders, this, this.vmRoleResourceExtensionViewModel));
        }

        protected override void LoadChildren()
        {            
            if (this.extensionSettings.ApplicationProfile.WindowsApplicationProfile != null)
            {
               this.LoadChildrenForWindowsAppProfile();
            }
            else if (this.extensionSettings.ApplicationProfile.LinuxApplicationProfile != null)
            {
                this.LoadChildrenForLinuxAppProfile();
            }
        }

        public void RemoveChild(TreeViewItemViewModel childItem)
        {
            var webDeployApplicationViewModel = childItem as WebDeployApplicationViewModel;
            if (webDeployApplicationViewModel != null)
            {
                webDeployApplicationViewModel.Cleanup();
                this.extensionSettings.ApplicationProfile.WindowsApplicationProfile.WebDeployApplications.Remove(webDeployApplicationViewModel.WebDeployApplication);
                this.Children.Remove(childItem);
                return;
            }

            var scriptAppViewModel = childItem as ScriptApplicationViewModel;
            if (scriptAppViewModel != null)
            {
                scriptAppViewModel.Cleanup();
                this.extensionSettings.ApplicationProfile.WindowsApplicationProfile.ScriptApplications.Remove(
                    scriptAppViewModel.ScriptApplication);
                this.Children.Remove(childItem);
                return;
            }

            var provisioningScriptViewModel = childItem as ProvisioningScriptViewModel;
            if (provisioningScriptViewModel != null)
            {
                provisioningScriptViewModel.Cleanup();
                this.extensionSettings.ApplicationProfile.WindowsApplicationProfile.ProvisioningScripts.Remove(
                    provisioningScriptViewModel.ProvisioningScript);
                this.Children.Remove(childItem);
                return;
            }

            var sqlDacViewModel = childItem as SqlDacApplicationViewModel;
            if (sqlDacViewModel != null)
            {
                sqlDacViewModel.Cleanup();
                this.extensionSettings.ApplicationProfile.WindowsApplicationProfile.SQLDacApplications.Remove(
                    sqlDacViewModel.SqlDacApplication);
                this.Children.Remove(childItem);
                return;
            }

            var sqlProfileViewModel = childItem as SqlProfileViewModel;
            if (sqlProfileViewModel != null)
            {
                sqlProfileViewModel.Cleanup();
                this.extensionSettings.ApplicationProfile.WindowsApplicationProfile.SQLProfile = null;
                this.Children.Remove(childItem);             
            }
        }

        public string this[string propertyName]
        {
            get
            {
                string error = null;
                switch (propertyName)
                {
                    case PropertyNames.Summary:
                        if (this.extensionSettings.ApplicationProfile.WindowsApplicationProfile != null && this.extensionSettings.ApplicationProfile.LinuxApplicationProfile != null)
                        {
                            error = "Both Windows And Linux Application Profile defined";
                        }
                        else if (this.extensionSettings.ApplicationProfile.WindowsApplicationProfile == null && this.extensionSettings.ApplicationProfile.LinuxApplicationProfile == null)
                        {
                            error = "Neither Windows Or Linux Application Profile defined)";
                        }
                        break;                   
                    case PropertyNames.Name:
                        error = ParameterizationHelper.ValidateCannotBeParameterizedBySpecification(this.Name, true);                   
                        break;
                    case PropertyNames.ApplicationPayloads:
                        // verify the payload referenced matches with the contents on the datapackage dir                        
                        if (this.vmRoleResourceExtensionViewModel.ResourceExtensionDefinition.DataPackage != null && 
                            this.vmRoleResourceExtensionViewModel.ResourceExtensionDefinition.DataPackage.Location != null &&
                            this.vmRoleResourceExtensionViewModel.ResourceExtensionStorageInfo != null && 
                            this.vmRoleResourceExtensionViewModel.ResourceExtensionStorageInfo.WorkingDir != null)
                        {
                            string fullPath = Path.Combine(this.vmRoleResourceExtensionViewModel.ResourceExtensionStorageInfo.WorkingDir, this.vmRoleResourceExtensionViewModel.ResourceExtensionDefinition.DataPackage.Location);
                            if (!Directory.Exists(fullPath))
                            {
                                //Check if all payload items are external.
                                //so essentially you should NOT get this error message, if all app payload items are external
                                //if some are external and some are internal, src folder is still needed (for internal)
                                bool anyInternal = this.vmRoleResourceExtensionViewModel.ApplicationProvileViewModel.ApplicationPayloads.Any(appPayloadViewModel => !appPayloadViewModel.IsExternal);
                                if (
                                    this.vmRoleResourceExtensionViewModel.ApplicationProvileViewModel.ApplicationPayloads != null &&
                                    this.vmRoleResourceExtensionViewModel.ApplicationProvileViewModel.ApplicationPayloads.Count > 0 &&
                                    anyInternal
                                    )
                                {
                                    error = string.Format("Datapackage folder {0} does not exist", fullPath);                                  
                                }                                                                       
                            }
                            else
                            {
                               List<string> files =  Directory.EnumerateFiles(fullPath).ToList();
                               List<string> dirs = Directory.EnumerateDirectories(fullPath).ToList();
                              
                               if ((this.applicationPayloadViewModels.Count < files.Count + dirs.Count) &&
                                   (this.vmRoleResourceExtensionViewModel.ResourceExtensionDataPackageViewModel.ExternalPayload.Count == 0))
                               {                                   
                                   //Data package contains either less content than is specified here 
                                   error = string.Format("Datapackage folder {0} contains less content than is referenced in application payload", fullPath);
                                  
                               }
                               else if ((this.applicationPayloadViewModels.Count > files.Count + dirs.Count)&&
                                        (this.vmRoleResourceExtensionViewModel.ResourceExtensionDataPackageViewModel.ExternalPayload.Count == 0))
                               {
                                   //Data package contains more  content than is specified here 
                                   List<string> unreferencedFiles = new List<string>();
                                   List<string> unreferencedDirectories = new List<string>();
                                   unreferencedFiles.AddRange(from file in files let referencedPayload = this.extensionSettings.ApplicationProfile.ApplicationPayload != null ? this.extensionSettings.ApplicationProfile.ApplicationPayload.Find(payload => file.EndsWith(payload.RelativePath, StringComparison.OrdinalIgnoreCase)) : null where referencedPayload == null select file);
                                   unreferencedDirectories.AddRange(from dir in dirs let referencedPayload = this.extensionSettings.ApplicationProfile.ApplicationPayload != null ? this.extensionSettings.ApplicationProfile.ApplicationPayload.Find(payload => dir.EndsWith(payload.RelativePath, StringComparison.OrdinalIgnoreCase)) : null where referencedPayload == null select dir);
                                   StringBuilder sb = new StringBuilder();
                                   sb.Append(string.Format("Datapackage folder {0} contains extra/unreferenced files.", fullPath));
                                   if (unreferencedFiles.Count > 0)
                                   {
                                       sb.Append("Delete:");
                                       foreach (string unreferencedFile in unreferencedFiles)
                                       {
                                           sb.Append(string.Format(" {0}", unreferencedFile));
                                       }
                                   }                                  
                                   if (unreferencedDirectories.Count > 0)
                                   {
                                       sb.Append(" .Delete dir:");
                                       foreach (string unreferencedDir in unreferencedDirectories)
                                       {
                                           sb.Append(string.Format(" {0}", unreferencedDir));
                                       }
                                   }
                                  
                                   error = sb.ToString();
                               }
                            }

                        }
                        break;
                }
                return error;               
            }
        }

        public string Error { get; set; }

        public ObservableCollection<CloudServiceModelValidationResult> ValidationResults { get; private set; }

        public void UpdateValidationResults()
        {
            this.IsExpanded = true;
            ModelValidationResultsHelper.UpdateValidationResults(this, typeof(PropertyNames));
            //Add any other cross-field validations error           
        }       
    }
}
